package com.atxiaodei.nio.nioday01;

import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @author wangmeng
 * @date 2020/9/13
 *
 * 一、函数式接口是什么？
 * 所谓的函数式接口，实际上就是接口里面只能有一个抽象方法的接口。我们上一节用到的Comparator接口就是一个典型的函数式接口，它只有一个抽象方法compare
 *
 * 二、函数式接口的特点
 * 接口有且仅有一个抽象方法，如上图的抽象方法compare
 * 允许定义静态非抽象方法
 * 允许定义默认defalut非抽象方法（default方法也是java8才有的，见下文）
 * 允许java.lang.Object中的public方法，如上图的方法equals。
 * FunctionInterface注解不是必须的，如果一个接口符合"函数式接口"定义，那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。
 * 如果编写的不是函数式接口，但是加上了@FunctionInterface，那么编译器会报错
 * 甚至可以说：函数式接口是专门为lambda表达式准备的，lambda表达式是只实现接口中唯一的抽象方法的匿名实现类。
 * 三、default关键字
 * 顺便讲一下default关键字，在java8之前
 *
 * 接口是不能有方法的实现，所有方法全都是抽象方法
 * 实现接口就必须实现接口里面的所有方法
 * 这就导致一个问题：当一个接口有很多的实现类的时候,修改这个接口就变成了一个非常麻烦的事,需要修改这个接口的所有实现类。
 *
 * 这个问题困扰了java工程师许久，不过在java8中这个问题得到了解决,没错就是default方法
 *
 * default方法可以有自己的默认实现，即有方法体。
 * 接口实现类可以不去实现default方法，并且可以使用default方法。
 * 四、JDK中的函数式接口举例
 * java.lang.Runnable,
 *
 * java.util.Comparator,
 *
 * java.util.concurrent.Callable
 *
 * java.util.function包下的接口，如Consumer、Predicate、Supplier等
 *
 * 不多说，直接干
 *
 **/
public class StreamApi8函数式接口Comparator {

    StreamTestVo e1 = new StreamTestVo(1,23,"M","Rick","Beethovan");
    StreamTestVo e2 = new StreamTestVo(2,13,"F","Martina","Hengis");
    StreamTestVo e3 = new StreamTestVo(3,43,"M","Ricky","Martin");
    StreamTestVo e4 = new StreamTestVo(4,26,"M","Jon","Lowman");
    StreamTestVo e5 = new StreamTestVo(5,19,"F","Cristine","Maria");
    StreamTestVo e6 = new StreamTestVo(6,15,"M","David","Feezor");
    StreamTestVo e7 = new StreamTestVo(7,68,"F","Melissa","Roy");
    StreamTestVo e8 = new StreamTestVo(8,79,"M","Alex","Gussin");
    StreamTestVo e9 = new StreamTestVo(9,15,"F","Neetu","Singh");
    StreamTestVo e10 = new StreamTestVo(10,45,"M","Naveen","Jain");


    List<StreamTestVo> StreamTestVos = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
    /**
     * 回顾下之前写StreamApi8之前的Api好多例子
     * 现在也写一个自定义Comparator排序
     */
    @Test
    public void test1(){
        StreamTestVos.sort(new Comparator<StreamTestVo>() {
            @Override
            public int compare(StreamTestVo o1, StreamTestVo o2) {
                return -(o1.getAge()-o2.getAge());  //负数返回 倒序，正数返回正序
            }
        });
        StreamTestVos.forEach(System.out::println);
        System.out.println("-----------------------------------------");
        // 现在我们用java8 lamdba表达式实现
        StreamTestVos.sort((x,y)->-(x.getAge()-y.getAge())); //负数返回 倒序，正数返回正序
        StreamTestVos.forEach(System.out::println);

    }

}
